package operadores.selecao;

import base.ParDeSolucoes;
import base.Populacao;
import base.Solucao;
import java.util.Collections;
import java.util.PriorityQueue;
import java.util.Queue;

// Representa o operador de seleção por Torneio.
public class SelecaoPorTorneio implements OperadorSelecao {

    private final int tamanhoDoTorneio;// quantidade de elementos para compor cada torneio

    public SelecaoPorTorneio(int tamanhoDoTorneio) {
        this.tamanhoDoTorneio = tamanhoDoTorneio;
    }

    @Override
    public ParDeSolucoes seleciona(Populacao populacao) {
        Solucao pai1 = vencedorDoTorneio(populacao);
        Solucao pai2;

        do {
            pai2 = vencedorDoTorneio(populacao);
        } while (pai2.equals(pai1));

        return new ParDeSolucoes(pai1, pai2);
    }

    // Realiza um torneio entre elementos aleatórios da população e retorna o
    // melhor dentre eles (o que tem custo menor).
    private Solucao vencedorDoTorneio(Populacao populacao) {
        Collections.shuffle(populacao.getSolucoes());

        Queue<Solucao> torneio = new PriorityQueue<>();

        for (int i = 0; i < tamanhoDoTorneio; i++) {
            torneio.offer(populacao.getSolucoes().get(i));
        }

        return torneio.poll();
    }
}
